var model;
var callbacks = $.Callbacks();

function makeMasterDetailFromEntity(entity, page) {
    makeMasterDetail("/mvc-basic/"+entity+"/tabbed?pg="+page);
}

function makeMasterDetailFromQuery(entity, queryString, queryObject) {
	makeMasterDetail("/mvc-basic/"+entity+"/query/tabbed?"+queryString);
	fillQueryFields(queryObject);
}

function fillQueryFields(queryObjects) {
	if (queryObjects) {
		var obj = JSON.parse(queryObjects);
		for (var key in obj) {
		  if (obj.hasOwnProperty(key)) {
		    $('#'+key).val(obj[key]);
		  }
		}
	}
}

function makeMasterDetail(url) {
    //$(document).ready(function() {
    	var filter = $('#filter_holder');
		var detail = $('#detail_holder');
		var table = $('#master_table');
		function success(result){
		    model = result;
			makeTabs(detail, result.tabs);
			makeCrudTable(table, result);
			makeFilterForm(filter, model);
			table.append(makePaginationButtons(model.pagination, model.UIModel));
		};
		makeAjaxCall(url, success);
	//});
}

function makePaginationButtons(pagination, model) {
    return '<button onclick="goToPage(\'' + 1 + '\', \'' + model.modelAttribute + '\')">First</button>'+
           '<button onclick="goToPage(\'' + pagination.previousPage + '\', \'' + model.modelAttribute + '\')">Previous</button>'+
           '<button onclick="goToPage(\'' + pagination.nextPage + '\', \'' + model.modelAttribute + '\')">Next</button>'+
           '<button onclick="goToPage(\'' + pagination.totalPages + '\', \'' + model.modelAttribute + '\')">Last</button>'+
           '<p>Showing page '+ pagination.currentPage +' of total '+ pagination.totalPages +' pages.</p>';
}

function makeDetailPaginationButtons(pagination, model) {
    return '<button onclick="refreshTab(\'' + 1 + '\', \'' + model.modelAttribute + '\')">First</button>'+
           '<button onclick="refreshTab(\'' + pagination.previousPage + '\', \'' + model.modelAttribute + '\')">Previous</button>'+
           '<button onclick="refreshTab(\'' + pagination.nextPage + '\', \'' + model.modelAttribute + '\')">Next</button>'+
           '<button onclick="refreshTab(\'' + pagination.totalPages + '\', \'' + model.modelAttribute + '\')">Last</button>'+
           '<p>Showing page '+ pagination.currentPage +' of total '+ pagination.totalPages +' pages.</p>';
}

function goToPage(page, entity) {
     window.location = "/mvc-basic/"+entity+"/list?pg="+page;
}

function makeTabs(el, models) {
     el.append('<div id="tabs"><ul></ul></div>');
     refreshTabs(models);
}

function refreshTabs(models) {
	var tabs = $('#tabs');
    var ul = tabs.find('ul');
    for (var i = 0; i < models.length; i++) {
       ul.append('<li><a href="#'+ models[i].modelAttribute +'">'+models[i].modelAttribute+'</a></li>');
    }
    mkTabs();
    for (var i = 0; i < models.length; i++) {
   		tabs.append('<div id="'+models[i].modelAttribute+'"></div>');
    }
}

function refreshGotovProizvodTab(edinicaMerkaId) {
	var div = $('#gotovProizvodView');
	url = '/mvc-basic/gotovProizvodView/'+edinicaMerkaId+'/details';
	function success(model){
		makeTable(div, model);
	    div.append(makeDetailPaginationButtons(model.pagination, model.UIModel));
	}
	makeAjaxCall(url, success);
}

function addEdinicaMerkaCallbacks() {
	callbacks.add(refreshGotovProizvodTab);
}

function refreshTab(pg, modelAttribute) {
	var div = $('#'+modelAttribute);
	url = '/mvc-basic/'+ modelAttribute +'/table?pg='+pg;
	function success(model){
		makeTable(div, model);
	    div.append(makeDetailPaginationButtons(model.pagination, model.UIModel));
	}
	makeAjaxCall(url, success);
}

function mkTabs() {
    $( "#tabs" ).tabs();
}

/**
Returns the string representation of the table represented by the json
*/
function makeTableFromJson(model) {
    var newDiv = $("#"+model.UIModel.modelAttribute);
    makeTable(newDiv, model);
    newDiv.append(makeDetailPaginationButtons(model.pagination, model.UIModel));
}

function makeTable(el, model) {
	el.empty();
	el.append('<table class="tablesorter" cellspacing="0"></table>');
	var table = el.find('table');

	var uiModel = model.UIModel.fieldLabels;
	var header = '';
	for ( var i = 0; i < uiModel.length; i++) {
		header = header + '<th>' + uiModel[i] + '</th>';
	}
	header = '<thead><tr>' + header + '</tr></thead>';
	table.append(header);

	var records = model.objects;
	for ( var i = 0; i < records.length; i++) {
		var obj = records[i];
		var rows = '';
		for ( var j = 0; j < model.UIModel.fieldNames.length; j++) {
			var attrValue = obj[model.UIModel.fieldNames[j]];
			rows = rows + '<td>' + attrValue + '</td>';
		}
		table.append('<tr>' + rows + '</tr>');
	}
}

function makeCrudTable(el, model) {
	el.append('<table class="tablesorter" cellspacing="0"></table>');
	var table = el.find('table');

	var uiModel = model.UIModel.fieldLabels;
	var header = '';
	for ( var i = 0; i < uiModel.length; i++) {
		header = header + '<th>' + uiModel[i] + '</th>';
	}
	header = header + '<th></th><th></th>';
	table.append('<thead><tr>' + header + '</tr></thead>');

	var records = model.objects;
	for ( var i = 0; i < records.length; i++) {
		var obj = records[i];
		var rows = '';
		for ( var j = 0; j < model.UIModel.fieldNames.length; j++) {
			var attrValue = obj[model.UIModel.fieldNames[j]];
			rows = rows + '<td onclick="fireClick('+i+')">' + attrValue + '</td>';
		}
		rows = rows + '<td>'+ createUpdateButton(i) +'</td><td>' + createDeleteButton(i) + '</td>';
		table.append('<tr>' + rows + '</tr>');
	}
}

// TODO to be refactored
function createDeleteButton(objectPosition) {
	return '<input type="image" src="/mvc-basic/resources/admin/images/icn_trash.png" ' +
		'title="Trash" onclick="deleteRecord(\'' + objectPosition + '\')"/>  ';
}

//TODO to be refactored
function createUpdateButton(objectPosition) {
	return '<input type="image" src="/mvc-basic/resources/admin/images/icn_edit.png" ' +
		'title="Edit" onclick="editRecord(\'' + objectPosition + '\')"/>  ';
}

function fireClick(objectPosition) {
	callbacks.fire(model.objects[objectPosition].id);
}

function deleteRecord(objectPosition) {
	if (confirm('Дали сте сигурни дека сакате да избришете?')) {
		var reloadFromServer = true;
		url = "/mvc-basic/"+ model.UIModel.modelAttribute +"/delete?id="+model.objects[objectPosition].id;
		function successs(result){
			//alert("Succesfully deleted"+result);
			window.location.reload(reloadFromServer);
		};
		makeAjaxCall(url, successs);
	}
}

function editRecord(objectPosition) {
	window.location = "/mvc-basic/"+ model.UIModel.modelAttribute +"/edit?id="+model.objects[objectPosition].id;
}

function makeDatePicker(el) {
    el.datepicker();
    el.datepicker( "option", "dateFormat", "dd-mm-yy" );
}

function getInputElString(name) {
    return '<input id="'+ name +'" name="'+ name +'" class="text ui-widget-content ui-corner-all" type="text">';
}

function makeFilterForm(div, model) {
	div.append('<header><h3>Search</h3></header>');
	div.append('<div class="module_content">');
	div.append('<form id="searchForm" action="/mvc-basic/'+ model.UIModel.modelAttribute +'/query/list"></form>');
	var form = div.find("form");
	for ( var j = 0; j < model.UIModel.fieldNames.length; j++) {
		var fieldName = model.UIModel.fieldNames[j];
		form.append('<label for="'+fieldName+'">'+fieldName+'</label>');
		form.append('<input id="'+fieldName+'" name="'+ fieldName +'" class="text ui-widget-content ui-corner-all" type="text">');
		form.append('<div class="spacer"></div>');
	}
	
	form.append('<p><input type="submit" value="Find"></p>');
	div.append('</div>');
}

function makeDateRange(name) {
    var idFrom = name+'From';
    var idTo = name+'To';
    var inputFrom = getInputElString(idFrom);
    var inputTo = getInputElString(idTo);
    $('#'+name).replaceWith(inputFrom + inputTo);
    makeDatePicker($('#'+idFrom));
    makeDatePicker($('#'+idTo));
}

function makeSearchFormForGotovProizvod(holder, errors) {
	var form = makeFormWithHiddenId(holder);
	makeTextField(form, 'GotovProizvod', 'gotovProizvod');
	makeEdinicaMerkaCombo(form);
	makeTipGotovProizvodCombo(form);
	makeSubmitButton(form);
	handleErrors(errors, form);
}

function makeSearchFormForSluzba(holder) {
	var form = makeFormWithHiddenId(holder);
	makeTextField(form, 'Инвеститор', 'investitor');
	makeSubmitButton(form);
}

function handleErrors(errors, div) {
	if (errors) {
		var obj = JSON.parse(errors);
		for ( var i = 0; i < obj.length; i++) {
			makeError(div, obj[i].defaultMessage, obj[i].field);
		}
	}
}

function makeSearchFormForIzvrsenaRealizacija(holder) {
	var form = makeFormWithHiddenId(holder);
	makeDateField(form, 'Datum', 'datum');
	makeProizvodenPogonCombo(form);
	makePartnerCombo(form);
	makeGotovProizvodCombo(form);
	makeTextField(form, 'eksternaRealKolicina', 'eksternaRealKolicina');
	makeTextField(form, 'eksternaRealIznosDen', 'eksternaRealIznosDen');
	makeTextField(form, 'internaRealKolicina', 'internaRealKolicina');
	makeTextField(form, 'internaRealIznosDen', 'internaRealIznosDen');
	makeTextField(form, 'zaSopstvenoRealKolicina', 'zaSopstvenoRealKolicina');
	makeTextField(form, 'zaSopstvenoRealIznosDen', 'zaSopstvenoRealIznosDen');
	makeSubmitButton(form);
}

function makeSearchFormForPartner(holder) {
	var form = makeFormWithHiddenId(holder);
	makeTextField(form, 'partner', 'partner');
	makeTipPartnerCombo(form);
	makeSluzbaCombo(form);
	makeTextField(form, 'tehnickiBroj', 'tehnickiBroj');
	makeSubmitButton(form);
}

function makeSearchFormForTipPartner(holder) {
	var form = makeFormWithHiddenId(holder);
	makeTextField(form, 'tipPartner', 'tipPartner');
	makeSubmitButton(form);
}

function makeSearchFormForTipGotovProizvod(holder) {
	var form = makeFormWithHiddenId(holder);
	makeTextField(form, 'Tip Gotov Proizvod', 'tipGotovProizvod');
	makeSubmitButton(form);
}

function makeSearchFormForTipProizvodenPogon(holder) {
	var form = makeFormWithHiddenId(holder);
	makeTextField(form, 'Tip Proizvoden Pogon', 'tipProizvodenPogon');
	makeSubmitButton(form);
}

function makeSearchFormForProizvodenPogon(holder) {
	var form = makeFormWithHiddenId(holder);
	makeTextField(form, 'proizvodenPogon', 'proizvodenPogon');
	makeTipProizvodenPogonCombo(form);
	makeSubmitButton(form);
}

function makeEditFormForEdinicaMerka(holder, id) {
	var form = makeFormWithHiddenId(holder);
	makeTextField(form, 'Edinica Merka', 'edinicaMerka');
	makeTextField(form, 'Edinica Merka Label', 'edinicaMerkaLabel');
	makeSubmitButton(form);
	
	var entity = "edinicaMerkaView";
	var url = '/mvc-basic/'+ entity +'/query/tabbed?id='+id;
	function success(result) {
		$('#id').val(result.objects[0].id);
		$('#edinicaMerka').val(result.objects[0].edinicaMerka);
		$('#edinicaMerkaLabel').val(result.objects[0].edinicaMerkaLabel);
	}
	makeAjaxCall(url, success);
}

function makeFormWithHiddenId(holder) {
	var div = $("#"+holder);
	div.append('<form id="createForm" action="/mvc-basic/'+ holder +'" method="post"></form>');
	var form = div.find('form');
	makeHiddenTextField(form, 'id');
	return form;
}

function makeEditFormForGotovProizvod(holder, id) {
	var entity = "gotovProizvodView";
	makeSearchFormForGotovProizvod(holder);
	var url = '/mvc-basic/'+ entity +'/query/tabbed?id='+id;
	function success(result) {
		$('#id').val(result.objects[0].id);
		$('#gotovProizvod').val(result.objects[0].gotovProizvod);
		selectItemByValue('edinicaMerka', result.objects[0].edinicaMerka);
		selectItemByValue('tipGotovProizvod', result.objects[0].tipGotovProizvod);
	}
	makeAjaxCall(url, success);
}

function makeEditFormForIzvrsenaRealizacija(holder, id) {
	var entity = "izvrsenaRealizacijaView";
	makeSearchFormForIzvrsenaRealizacija(holder);
	var url = '/mvc-basic/'+ entity +'/query/tabbed?id='+id;
	function success(result) {
		$('#id').val(result.objects[0].id);
		$('#datum').val(result.objects[0].datum);
		selectItemByValue('proizvodenPogon', result.objects[0].proizvodenPogon);
		selectItemByValue('partner', result.objects[0].partner);
		selectItemByValue('gotovProizvod', result.objects[0].gotovProizvod);
		$('#eksternaRealKolicina').val(result.objects[0].eksternaRealKolicina);
		$('#eksternaRealIznosDen').val(result.objects[0].eksternaRealIznosDen);
		$('#internaRealKolicina').val(result.objects[0].internaRealKolicina);
		$('#internaRealIznosDen').val(result.objects[0].internaRealIznosDen);
		$('#zaSopstvenoRealKolicina').val(result.objects[0].zaSopstvenoRealKolicina);
		$('#zaSopstvenoRealIznosDen').val(result.objects[0].zaSopstvenoRealIznosDen);
	}
	makeAjaxCall(url, success);
}

function makeEditFormForPartner(holder, id) {
	var entity = "partnerView";
	makeSearchFormForPartner(holder);
	var url = '/mvc-basic/'+ entity +'/query/tabbed?id='+id;
	function success(result) {
		$('#id').val(result.objects[0].id);
		$('#partner').val(result.objects[0].partner);
		selectItemByValue('tipPartner', result.objects[0].tipPartner);
		selectItemByValue('investitor', result.objects[0].investitor);
		$('#tehnickiBroj').val(result.objects[0].tehnickiBroj);
	}
	makeAjaxCall(url, success);
}

function makeEditFormForTipPartner(holder, id) {
	var entity = "tipPartnerView";
	makeSearchFormForTipPartner(holder);
	var url = '/mvc-basic/'+ entity +'/query/tabbed?id='+id;
	function success(result) {
		$('#id').val(result.objects[0].id);
		$('#tipPartner').val(result.objects[0].tipPartner);
	}
	makeAjaxCall(url, success);
}

function makeEditFormForTipGotovProizvod(holder, id) {
	var entity = "tipGotovProizvodView";
	makeSearchFormForTipGotovProizvod(holder);
	var url = '/mvc-basic/'+ entity +'/query/tabbed?id='+id;
	function success(result) {
		$('#id').val(result.objects[0].id);
		$('#tipGotovProizvod').val(result.objects[0].tipGotovProizvod);
	}
	makeAjaxCall(url, success);
}

function makeEditFormForTipProizvodenPogon(holder, id) {
	var entity = "tipProizvodenPogonView";
	makeSearchFormForTipProizvodenPogon(holder);
	var url = '/mvc-basic/'+ entity +'/query/tabbed?id='+id;
	function success(result) {
		$('#id').val(result.objects[0].id);
		$('#tipProizvodenPogon').val(result.objects[0].tipProizvodenPogon);
	}
	makeAjaxCall(url, success);
}

function makeEditFormForSluzba(holder, id) {
	var entity = "sluzbaView";
	makeSearchFormForSluzba(holder);
	var url = '/mvc-basic/'+ entity +'/query/tabbed?id='+id;
	function success(result) {
		$('#id').val(result.objects[0].id);
		$('#investitor').val(result.objects[0].investitor);
	}
	makeAjaxCall(url, success);
}

function makeEditFormForProizvodenPogon(holder, id) {
	var entity = "proizvodenPogonView";
	makeSearchFormForProizvodenPogon(holder);
	var url = '/mvc-basic/'+ entity +'/query/tabbed?id='+id;
	function success(result) {
		$('#id').val(result.objects[0].id);
		$('#proizvodenPogon').val(result.objects[0].proizvodenPogon);
		selectItemByValue('tipProizvodenPogon', result.objects[0].tipProizvodenPogon);
	}
	makeAjaxCall(url, success);
}

function makeAjaxCall(url, success) {
	$.ajax({url:url,
		success:function(result){
			success(result);
		},
		dataType: "json",
		contentType: "application/json; charset=utf-8",
		async: false
	});
}

function selectItemByValue(elmnt, value){
    // Set value to the jQueryUI combo box (what the user sees)
	$('#'+elmnt+'Combo').val(value);
	// Set value to the combo box (what is actually selected)
	$('#'+elmnt).find("option").filter(function() {
	    //may want to use $.trim in here
	    return $(this).text() == value; 
	}).prop('selected', true);
}

function makeReportForm(formId, entity) {
	var el = $('#'+formId);
	el.append('<form id="searchForm" action="/mvc-basic/report/'+entity+'/report" method="get"></form>');
	var form = el.find('#searchForm');
	makeDateField(form, 'Date From', 'dateFrom');
	makeDateField(form, 'Date To', 'dateTo');
	form.append('<p><input type="submit" value="Find"></p>');
}

function makeEdinicaMerkaCombo(form) {
	makeCombo(form, 'EdinicaMerka', 'edinicaMerkaView', 'id', 'edinicaMerka');
}

function makeTipGotovProizvodCombo(form) {
	makeCombo(form, 'TipGotovProizvod', 'tipGotovProizvodView', 'id', 'tipGotovProizvod');
}

function makeGotovProizvodCombo(form) {
	makeCombo(form, 'GotovProizvod', 'gotovProizvodView', 'id', 'gotovProizvod');
}

function makeProizvodenPogonCombo(form) {
	makeCombo(form, 'ProizvodenPogon', 'proizvodenPogonView', 'id', 'proizvodenPogon');
}

function makePartnerCombo(form) {
	makeCombo(form, 'Partner', 'partnerView', 'id', 'partner');
}

function makeTipPartnerCombo(form) {
	makeCombo(form, 'Tip Partner', 'tipPartnerView', 'id', 'tipPartner');
}

function makeSluzbaCombo(form) {
	makeCombo(form, 'Инвеститор', 'sluzbaView', 'id', 'investitor');
}

function makeTipProizvodenPogonCombo(form) {
	makeCombo(form, 'Tip Proizvoden Pogon', 'tipProizvodenPogonView', 'id', 'tipProizvodenPogon');
}

function makeTextField(div, label, name) {
	makeLabel(div, label, name);
	div.append('<input id="'+ name +'" name="'+ name +'" class="text ui-widget-content ui-corner-all" type="text">');
	div.append('<div class="spacer"></div>');
}

function makeDateField(div, label, name) {
	makeLabel(div, label, name);
	div.append(getInputElString(name));
    var el = div.find('#'+name);
	makeDatePicker(el);
	div.append('<div class="spacer"></div>');
}

function makeHiddenTextField(div, name) {
	div.append('<input id="'+ name +'" name="'+ name +'" class="text ui-widget-content ui-corner-all" type="hidden">');
}

function makeCombo(div, label, entity, valueField, textField) {
	makeLabel(div, label, textField);
	div.append('<select id="'+textField+'" name="'+ textField +'" style="visibility:hidden;width: 1px"></select>');
	var combo = div.find('#'+textField);
	url = '/mvc-basic/'+ entity +'/getAll?ob=' + textField;
	function success(result){
	    fillCombo(combo, result, valueField, textField);
	    $( "#"+textField ).combobox();
	}
	makeAjaxCall(url, success);
	div.append('<div class="spacer"></div>');
}

function fillCombo(combo, model, valueField, textField) {
	combo.append('<option></option>');
	var records = model.objects;
	for ( var i = 0; i < records.length; i++) {
		var obj = records[i];
		combo.append('<option value="'+ obj[valueField] +'">'+ obj[textField] +'</option>');
	}
	
}

function makeError(div, label, name) {
	div.find("#"+name+'Label').before('<label>'+ label +'</label><div class="spacer"></div>');
}

function makeLabel(div, label, name) {
	div.append('<label id="'+name+'Label" for="'+ name +'">'+ label +'</label>');
}

function makeSubmitButton(div) {
	div.append('<p><input type="submit" value="Submit"></p>');
}

